package com.zmn.oms.dubbo.impl.zmn.channel.order;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.channel.common.dro.ChannelSettleDRO;
import com.zmn.base.channel.common.enums.ChannelSettleNodeEnum;
import com.zmn.base.channel.dubbo.interfaces.channel.settle.ChannelSettleListRemoteService;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.response.ResponseUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.common.constant.CompanyConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.OrderTagConsts;
import com.zmn.oms.common.enums.EncryptFieldTypeEnum;
import com.zmn.oms.dubbo.dto.zmn.order.*;
import com.zmn.oms.dubbo.interfaces.zmn.channel.order.ZsChannelOrderListRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.oms.model.entity.work.list.OrderWorkChannelQuery;
import com.zmn.oms.model.vo.work.detail.ZsOrderWorkDetailCommentVO;
import com.zmn.oms.model.vo.work.detail.ZsOrderWorkDetailContactVO;
import com.zmn.oms.model.vo.work.detail.ZsOrderWorkDetailVO;
import com.zmn.oms.model.vo.work.detail.ZsOrderWorkDetailWarrantyVO;
import com.zmn.oms.model.vo.work.list.ZsOrderWorkChannelVO;
import com.zmn.oms.services.interfaces.orderencrypt.OrderEncryptService;
import com.zmn.oms.zmn.aop.ZsChannelOrderLogUtils;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import io.shardingsphere.api.HintManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：商家中心订单统计
 *
 * @author yule
 * @date 2019/04/10 10:05
 */
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "false")
public class ZsChannelOrderListRemoteServiceImpl implements ZsChannelOrderListRemoteService {

	private static final Logger logger = LoggerFactory.getLogger(ZsChannelOrderListRemoteServiceImpl.class);

	static final String TAG = "啄木鸟-商家渠道";

	@Autowired
	private ZsOrderWorkQueryBService orderWorkQueryBService;
	@Autowired
	private OrderWorkListBService orderWorkListBService;
	@Autowired
	private OrderEncryptService orderEncryptService;
	@Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
	private ChannelSettleListRemoteService channelSettleListRemoteService;

	// 完成节点 改为 领单节点 结算
	private Map<Integer, String> FULFILL_TO_TAKE_NODE_MAP = Maps.newHashMap();
	{
		FULFILL_TO_TAKE_NODE_MAP.put(34046, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(1451, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(10114, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(1466, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(1324, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(33100, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(33034, "2022-05-01 00:00:00");
		FULFILL_TO_TAKE_NODE_MAP.put(41910, "2022-05-01 00:00:00");
		// test2 测试
		// FULFILL_TO_TAKE_NODE_MAP.put(41459, "2022-5-01 00:00:00");
	}

	//  领单节点 改为 完成节点 结算
	private Map<Integer, String> TAKE_TO_FULFILL_NODE_MAP = Maps.newHashMap();
	{
		TAKE_TO_FULFILL_NODE_MAP.put(41245, "2022-05-01 00:00:00");
		// test2 测试
		// TAKE_TO_FULFILL_NODE_MAP.put(1557, "2022-5-01 00:00:00");
	}

	@Override
	public ResponseDTO<OrderDetailDRO> findOrderDetail(Long orderId) {

		Objects.requireNonNull(orderId);
		logger.info("[{}] 商家渠道订单查询：{}", TAG, "orderId:" + orderId);

		OrderDetailDRO orderDetailDRO = new OrderDetailDRO();

		try (HintManager hintManager = HintManager.getInstance()) {
			hintManager.setMasterRouteOnly();

			ZsOrderWorkDetailVO orderWorkDetail = orderWorkQueryBService.findOrderWorkDetail(orderId, orderId);

			if (orderWorkDetail != null) {
				List<OrderLog> orderLogList = orderWorkDetail.getLogList();
				if (!CollectionUtils.isEmpty(orderLogList)) {
					//商家渠道操作日志过滤
					List<OrderLog> neworderLogList = orderLogList.stream().filter(e -> ZsChannelOrderLogUtils.CHANNEL_ORDER_LOG_TYPE_LIST.contains(e.getType())).collect(Collectors.toList());
					orderWorkDetail.setLogList(neworderLogList);
				}
			}

			BeanMapper.copy(orderWorkDetail, orderDetailDRO);
			orderDetailDRO.setWorkId(orderId);
			orderDetailDRO.setOrderId(orderId);

			// 联系信息
			ZsOrderWorkDetailContactVO contactVO = orderWorkDetail.getContactVO();
			if (contactVO != null) {
				orderDetailDRO.setContact(BeanMapper.map(contactVO, OrderContactDRO.class));
			}

			//保修信息
			ZsOrderWorkDetailWarrantyVO warrantyVO = orderWorkDetail.getWarranty();
			if (warrantyVO != null) {
				orderDetailDRO.setWarranty(BeanMapper.map(warrantyVO, OrderDetailWarrantyDRO.class));
			}

			// 评价
			ZsOrderWorkDetailCommentVO commentVO = orderWorkDetail.getUserCommentVO();
			if (commentVO != null) {
				orderDetailDRO.setComment(BeanMapper.map(commentVO, OrderCommentDRO.class));
			}
		}

		return ResponseUtil.responseSuccess(orderDetailDRO, GlobalConsts.SUCCESS_MSG);
	}


	@Override
	public ResponseDTO<ChannelOrderListPageDRO> listOrder(ChannelOrderListQueryDIO orderListQueryDIO) {

		logger.info("[{}] 商家渠道订单列表：{}", TAG, orderListQueryDIO);

		OrderWorkChannelQuery query = BeanMapper.map(orderListQueryDIO, OrderWorkChannelQuery.class);
		query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW));
		query.setDefaultOrder(GlobalConsts.YES);
		// 不查询未成单数据
		query.setNonTagId(OrderTagConsts.TAG_ID_UN_AVAILABLE_SERVICE);
		String orderField = orderListQueryDIO.getOrderField();
		query.setOrderField("receiveTime");
		if (StringUtil.isNotBlank(orderField)) {
			query.setOrderField(orderField);
		}

		// 已领单标示
//		boolean masterTakeOrder = Objects.equals(GlobalConsts.YES, orderListQueryDIO.getMasterTakeStatus());
//        if (masterTakeOrder) {
//            query.setExistChannelStatementCanTime(GlobalConsts.YES);
//        }

		// 状态标示
		Integer status = orderListQueryDIO.getStatus();
        if (status != null) {
            switch (status) {
				case OrderConsts.QUERY_TAB_ONE:// 服务中
					// 进行中-已录入、已确认、已分单、已派单、已领单、已上门
					query.setResultStatus(Lists.newArrayList(OrderStatusConsts.WORK_RESULT_DOING));
					query.setStatusList(Lists.newArrayList(
							OrderStatusConsts.WORK_STATUS_INPUT,
							OrderStatusConsts.WORK_STATUS_CONFIRM,
							OrderStatusConsts.WORK_STATUS_ASSIGN,
							OrderStatusConsts.WORK_STATUS_DISTRIBUTE,
							OrderStatusConsts.WORK_STATUS_TAKE,
							OrderStatusConsts.WORK_STATUS_VISIT
					));
					break;
				case OrderConsts.QUERY_TAB_TWO:// 已完成
					// 已完成(服务完成 + 已完成 + 已收单 + 已算账)
					query.setStatusList(Lists.newArrayList(
							OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE,
							OrderStatusConsts.WORK_STATUS_COMPLETE,
							OrderStatusConsts.WORK_STATUS_CHECKOUT,
							OrderStatusConsts.WORK_STATUS_ACCOUNT));
					break;
                case OrderConsts.QUERY_TAB_THREE:// 已取消
                    // 取消(已录入、已分单、已确认、已派单、已领单、已上门)
                    // 失败/取消 -- 未完成
                    query.setResultStatus(Lists.newArrayList(OrderStatusConsts.WORK_RESULT_FAIL, OrderStatusConsts.WORK_RESULT_DISCARD));
                    query.setExistCompleteTime(GlobalConsts.NO);
                    break;
                default:
                    // 不处理
            }
		}

		// TODO lujia 紧急需求 - 1408
		//  seo渠道B/G/H/E/D针对这几个渠道 ， 在小程序端口或者商家门户，隐藏弃单的订单。
		// 渠道ID:1451，1519，33034，1442，1438
		// 最新需求：删除1519弃单隐藏，
		List<Integer> speChannel = Arrays.asList(1451, 33034, 1442, 1438);
		if ((speChannel.contains(orderListQueryDIO.getChannelId()) || speChannel.contains(orderListQueryDIO.getSourceChannelId()))
				&& CollectionUtil.isNullOrEmpty(query.getResultStatus())) {
			query.setResultStatus(Lists.newArrayList(OrderStatusConsts.WORK_RESULT_DOING, OrderStatusConsts.WORK_RESULT_SUCCESS, OrderStatusConsts.WORK_RESULT_FAIL));
		}

		// 获取查询
		NativeSearchQuery searchQuery = this.getNativeSearchQueryByQuery(orderListQueryDIO, query);

		// 结算方式查询处理
		// 是否根据来源渠道和下单渠道组合查询(以来源渠道时间为分界，源渠道时间，之前的时间查询下单渠道，之后的查询来源渠道)
		boolean hasSourceChannelQuery = NumberUtil.isNotNullOrZero(orderListQueryDIO.getSourceChannelId()) &&
				StringUtils.isNotBlank(orderListQueryDIO.getSourceChannelDisplayTime());
		Integer channelId = hasSourceChannelQuery ? orderListQueryDIO.getSourceChannelId() : orderListQueryDIO.getChannelId();
		ChannelSettleNodeEnum channelSettleNode = this.getChannelSettleNode(channelId);
		searchQuery = this.getNativeSearchQueryByChannelSettle(searchQuery, channelSettleNode, channelId);

		// 执行查询
		List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkBySearchQuery(query, searchQuery);

		// 解密电话和地址
		orderEncryptService.batchDecryptEsOrderWork(esOrderWorks, EncryptFieldTypeEnum.USER_TELPHONE, EncryptFieldTypeEnum.USER_ADDRESS);
		// 转 vo
		List<ZsOrderWorkChannelVO> list = Lists.newArrayList();

		esOrderWorks.forEach((esOrderWork -> {
			ZsOrderWorkChannelVO vo = BeanMapper.map(esOrderWork, ZsOrderWorkChannelVO.class);
			vo.setContactName(esOrderWork.getContact().getContactName());
			vo.setContactPhone(esOrderWork.getContact().getPhone());
			vo.setAddress(esOrderWork.getContact().getAddress());
			vo.setStreet(esOrderWork.getContact().getStreet());
			vo.setProvinceName(esOrderWork.getProvinceName());
			vo.setCityName(esOrderWork.getCityName());
			vo.setCountyName(esOrderWork.getCountyName());
			vo.setProvinceId(esOrderWork.getProvinceId());
			vo.setCityId(esOrderWork.getCityId());
			vo.setCountyId(esOrderWork.getCountyId());
			vo.setCompleteTime(esOrderWork.getCompleteTime());
			vo.setRemark(esOrderWork.getRemark());
			vo.setChannelPrepayAmount(esOrderWork.getChannelPrepayAmount());
			list.add(vo);
		}));

		List<ChannelOrderDRO> orderDROList = BeanMapper.mapList(list, ChannelOrderDRO.class);

		ChannelOrderListPageDRO pageDRO = new ChannelOrderListPageDRO();
		pageDRO.setTotalCount(query.getTotalCount());
		pageDRO.setList(orderDROList);

		return ResponseUtil.responseSuccess(pageDRO, GlobalConsts.SUCCESS_MSG);
	}

	/**
	 * 获取查询语句
	 *
	 * @param orderListQueryDIO
	 * @param query
	 * @return
	 */
	private NativeSearchQuery getNativeSearchQueryByQuery(ChannelOrderListQueryDIO orderListQueryDIO, OrderWorkChannelQuery query) {

		// 是否根据来源渠道和下单渠道组合查询(以来源渠道时间为分界，源渠道时间，之前的时间查询下单渠道，之后的查询来源渠道)
		boolean hasSourceChannelQuery = NumberUtil.isNotNullOrZero(orderListQueryDIO.getSourceChannelId()) &&
				StringUtils.isNotBlank(orderListQueryDIO.getSourceChannelDisplayTime());

		// 只根据下单渠道查询
		if (!hasSourceChannelQuery) {
			NativeSearchQuery searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
			logger.info("[{}] log0--->{}", TAG, searchQuery.getQuery().toString());
			return searchQuery;
		}

		return this.getSourceChannelNativeSearchQueryByQuery(query, orderListQueryDIO.getSourceChannelDisplayTime());
	}

	/**
	 * 以来源渠道时间为分界，源渠道时间之前的时间查询下单渠道，之后的查询来源渠道
	 * @param query
	 * @param sourceChannelDisplayTime 来源渠道时间
	 * @return
	 */
	private NativeSearchQuery getSourceChannelNativeSearchQueryByQuery(OrderWorkChannelQuery query, String sourceChannelDisplayTime) {
		String receiveTime = query.getReceiveTime();
		Integer sourceChannelId = query.getSourceChannelId();

		// 清空下单时间、来源渠道、下单渠道
		query.setReceiveTime(null);
		query.setSourceChannelId(null);
		query.setChannelId(null);

		// String sourceChannelDisplayTime = "2021-10-01 00:00:00";
		long sourceChannelStartTimestamp = DateUtil.toTimestamp(sourceChannelDisplayTime, DateUtil.FORMAT_DEFAULT);

		NativeSearchQuery searchQuery;

		if (StringUtils.isBlank(receiveTime)) {
			BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

			// 按照下单渠道查询，最大时间小于来源渠道时间
			BoolQueryBuilder channelBuilder = QueryBuilders.boolQuery();
			channelBuilder.must(QueryBuilders.termQuery("channelId", sourceChannelId));
			RangeQueryBuilder channelReceiveTimeQueryBuilder = QueryBuilders.rangeQuery("receiveTime");
			channelReceiveTimeQueryBuilder.lt(sourceChannelDisplayTime); // 最大时间
			channelBuilder.must(channelReceiveTimeQueryBuilder);
			boolQueryBuilder.should(channelBuilder);

			// 按照来源渠道查询，最小时间大约来源渠道时间
			BoolQueryBuilder sourceChannelBuilder = QueryBuilders.boolQuery();
			sourceChannelBuilder.must(QueryBuilders.termQuery("sourceChannelId", sourceChannelId));
			RangeQueryBuilder sourceChannelReceiveTimeQueryBuilder = QueryBuilders.rangeQuery("receiveTime");
			sourceChannelReceiveTimeQueryBuilder.gte(sourceChannelDisplayTime); // 最小时间
			sourceChannelBuilder.must(sourceChannelReceiveTimeQueryBuilder);
			boolQueryBuilder.should(sourceChannelBuilder);

			searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
			List<QueryBuilder> filter = ((BoolQueryBuilder) searchQuery.getQuery()).filter();
			filter.add(boolQueryBuilder);

			logger.info("[{}] log1--->{}, {}", TAG, sourceChannelId, searchQuery.getQuery().toString());
			return searchQuery;
		}

		// 根据下单时间查询
		String[] dateArr = receiveTime.split(",", -1);
		long startTimestamp = StringUtils.isNotBlank(dateArr[0]) ? DateUtil.toTimestamp(dateArr[0], DateUtil.FORMAT_DEFAULT) : 0;
		long endTimestamp = StringUtils.isNotBlank(dateArr[1]) ? DateUtil.toTimestamp(dateArr[1], DateUtil.FORMAT_DEFAULT) : DateUtil.getNowTimestamp();

		// 开始时间 大于 处理时间，直接查询来源渠道
		if (startTimestamp >= sourceChannelStartTimestamp) {
			query.setSourceChannelId(sourceChannelId);
			query.setReceiveTime(receiveTime);

			searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
			logger.info("[{}] log2--->{}, {}", TAG, sourceChannelId, searchQuery.getQuery().toString());

			return searchQuery;
		}

		// 结束时间 小于 处理时间，直接查询
		if (endTimestamp < sourceChannelStartTimestamp) {
			query.setChannelId(sourceChannelId);
			query.setReceiveTime(receiveTime);
			searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
			logger.info("[{}] log3--->{}, {}", TAG, sourceChannelId, searchQuery.getQuery().toString());

			return searchQuery;
		}

		// 跨时间查询
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

		// 处理渠道结束时间
		BoolQueryBuilder channelBuilder = QueryBuilders.boolQuery();
		channelBuilder.must(QueryBuilders.termQuery("channelId", sourceChannelId));
		RangeQueryBuilder channelReceiveTimeQueryBuilder = QueryBuilders.rangeQuery("receiveTime");
		channelReceiveTimeQueryBuilder.gte(dateArr[0]); // 最小时间
		channelReceiveTimeQueryBuilder.lt(sourceChannelDisplayTime); // 最大时间
		channelBuilder.must(channelReceiveTimeQueryBuilder);
		boolQueryBuilder.should(channelBuilder);

		// 处理来源渠道开始时间
		BoolQueryBuilder sourceChannelBuilder = QueryBuilders.boolQuery();
		sourceChannelBuilder.must(QueryBuilders.termQuery("sourceChannelId", sourceChannelId));
		RangeQueryBuilder sourceChannelReceiveTimeQueryBuilder = QueryBuilders.rangeQuery("receiveTime");
		sourceChannelReceiveTimeQueryBuilder.gte(sourceChannelDisplayTime); // 最小时间
		sourceChannelReceiveTimeQueryBuilder.lte(dateArr[1]); // 来源渠道最大时间

		sourceChannelBuilder.must(sourceChannelReceiveTimeQueryBuilder);
		boolQueryBuilder.should(sourceChannelBuilder);

		searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
		List<QueryBuilder> filter = ((BoolQueryBuilder) searchQuery.getQuery()).filter();
		filter.add(boolQueryBuilder);
		logger.info("[{}] log4--->{}, {}", TAG, sourceChannelId, searchQuery.getQuery().toString());

		return searchQuery;
	}

	/**
	 * 渠道结算方式处理
	 *
	 * @param searchQuery
	 * @param channelId
	 * @return
	 */
	private NativeSearchQuery getNativeSearchQueryByChannelSettle(NativeSearchQuery searchQuery, ChannelSettleNodeEnum channelSettleNode, Integer channelId) {
		// ChannelSettleNodeEnum channelSettleNode = this.getChannelSettleNode(channelId);
		// 特殊渠道处理，渠道领单和完成节点配置调整兼容处理

		// 结算节点定义
		// 领单：非家修匠+分单时间 or 家修匠数据+领单时间
		// 完成：全部(不区分节点，查询所有订单)

		// 完成节点 改为 领单节点 结算
		if (Objects.equals(channelSettleNode.getCode(), ChannelSettleNodeEnum.GET_A_SINGLE.getCode())
				&& FULFILL_TO_TAKE_NODE_MAP.containsKey(channelId)) {
			searchQuery = this.getNativeSearchQueryByFulfillToTakeNodeSettle(searchQuery, channelId);
			logger.info("[{}] log--完成节点 改为 领单节点 结算处理--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());
			return searchQuery;
		}

		// 领单节点 改为 完成节点 结算
		if (Objects.equals(channelSettleNode.getCode(), ChannelSettleNodeEnum.FULFILL.getCode())
				&& TAKE_TO_FULFILL_NODE_MAP.containsKey(channelId)) {
			searchQuery = this.getNativeSearchQueryByTakeToFulfillNodeSettle(searchQuery, channelId);
			logger.info("[{}] log--领单节点 改为 完成节点 结算--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());
			return searchQuery;
		}

		// 领单节点正常查询
		if (Objects.equals(channelSettleNode.getCode(), ChannelSettleNodeEnum.GET_A_SINGLE.getCode())) {
			BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
			boolQueryBuilder.must(QueryBuilders.existsQuery("channelStatementCanTime"));
			List<QueryBuilder> filter = ((BoolQueryBuilder) searchQuery.getQuery()).filter();
			filter.add(boolQueryBuilder);
			logger.info("[{}] log--领单节点正常查询--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());
		}

		return searchQuery;
	}

	/**
	 * 完成节点 改为 领单节点 结算处理
	 * @param searchQuery
	 * @return
	 */
	private NativeSearchQuery getNativeSearchQueryByFulfillToTakeNodeSettle(NativeSearchQuery searchQuery, Integer channelId) {
		String fulfillToTakeNodeSettleTime = FULFILL_TO_TAKE_NODE_MAP.get(channelId);

		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

		// 1、查询转化时间前的  完成节点数据
		BoolQueryBuilder fulfillSettleBuilder = QueryBuilders.boolQuery();
		fulfillSettleBuilder.must(QueryBuilders.rangeQuery("receiveTime").lt(fulfillToTakeNodeSettleTime));
		boolQueryBuilder.should(fulfillSettleBuilder);

//		// 2、查询转化后时间后的 领单节点数据
//		// 领单节点数据 (非家修匠+分单时间 or 家修匠数据+领单时间)
//		BoolQueryBuilder takeNodeSettleBuilder = QueryBuilders.boolQuery();
//
//		// 领单节点数据-非家修匠+分单时间
//		BoolQueryBuilder takeNode1Builder = QueryBuilders.boolQuery();
//		takeNode1Builder.mustNot(QueryBuilders.termQuery("companyId", CompanyConsts.ZMN_JXJ_COMPANY_ID));
//		takeNode1Builder.must(QueryBuilders.rangeQuery("assignTime").gte(fulfillToTakeNodeSettleTime));
//
//		// 领单节点数据-家修匠数据+领单时间
//		BoolQueryBuilder takeNode2Builder = QueryBuilders.boolQuery();
//		takeNode2Builder.must(QueryBuilders.termQuery("companyId", CompanyConsts.ZMN_JXJ_COMPANY_ID));
//		takeNode2Builder.must(QueryBuilders.rangeQuery("takeTime").gte(fulfillToTakeNodeSettleTime));
//
//		// or 查询
//		takeNodeSettleBuilder.should(takeNode1Builder);
//		takeNodeSettleBuilder.should(takeNode2Builder);

		// 2、查询转化后时间后的 可结算时间
		BoolQueryBuilder takeSettleBuilder = QueryBuilders.boolQuery();
		takeSettleBuilder.must(QueryBuilders.rangeQuery("receiveTime").gte(fulfillToTakeNodeSettleTime));
		takeSettleBuilder.must(QueryBuilders.existsQuery("channelStatementCanTime"));
		boolQueryBuilder.should(takeSettleBuilder);

		// 3 组合条件
		List<QueryBuilder> filter = ((BoolQueryBuilder) searchQuery.getQuery()).filter();
		filter.add(boolQueryBuilder);

		return searchQuery;
	}

	/**
	 * 领单节点 改为 完成节点 结算处理
	 * @param searchQuery
	 * @return
	 */
	private NativeSearchQuery getNativeSearchQueryByTakeToFulfillNodeSettle(NativeSearchQuery searchQuery, Integer channelId) {
		String takeToFulfillNodeSettleTime = TAKE_TO_FULFILL_NODE_MAP.get(channelId);

		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

		// 1、查询转化时间前的  可结算时间不为空的数据
		BoolQueryBuilder takeSettleBuilder = QueryBuilders.boolQuery();
		takeSettleBuilder.must(QueryBuilders.rangeQuery("receiveTime").lt(takeToFulfillNodeSettleTime));
		takeSettleBuilder.must(QueryBuilders.existsQuery("channelStatementCanTime"));
		boolQueryBuilder.should(takeSettleBuilder);

		// 2、查询转化后时间后的 全部数据
		BoolQueryBuilder fulfillSettleBuilder = QueryBuilders.boolQuery();
		fulfillSettleBuilder.must(QueryBuilders.rangeQuery("receiveTime").gte(takeToFulfillNodeSettleTime));

		boolQueryBuilder.should(fulfillSettleBuilder);

		// 3 组合条件
		List<QueryBuilder> filter = ((BoolQueryBuilder) searchQuery.getQuery()).filter();
		filter.add(boolQueryBuilder);

		return searchQuery;
	}

	@Override
	public ResponseDTO<OrderCountDRO> orderCountByQuery(Integer channelId) {

		Objects.requireNonNull(channelId);
		logger.info("[{}] 商家渠道订单统计：{}", TAG, "channelId:" + channelId);

		// 是否为领单可结算渠道
		// boolean takeSettle = takeSettle(channelId);
		ChannelSettleNodeEnum channelSettleNode = this.getChannelSettleNode(channelId);

		OrderCountDRO orderCountDRO = new OrderCountDRO();

		OrderWorkQuery query = new OrderWorkQuery();
		query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW));
		query.setChannelIdList(Lists.newArrayList(channelId));
		//今日订单数量
		Date now = DateUtil.getNow();
		String receiveTime = DateUtil.toString(now, DateUtil.FORMAT_DATE);
		query.setReceiveTime(receiveTime + "," + receiveTime);
		// 不查询未成单数据
		query.setNonTagId(OrderTagConsts.TAG_ID_UN_AVAILABLE_SERVICE);

		// 可结算方式查询
		NativeSearchQuery searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
		searchQuery = this.getNativeSearchQueryByChannelSettle(searchQuery, channelSettleNode, channelId);
		logger.info("[{}] log--今日订单数量--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());

		Integer todayOrderCount = orderWorkListBService.countOrderWorkByQuery(query);
		orderCountDRO.setTodayOrderCount(todayOrderCount);

		query = new OrderWorkQuery();
		query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW));
		query.setChannelIdList(Lists.newArrayList(channelId));
		//剩余服务中：所有正在服务中的订单（结果为:进行中  状态为：已录入+分单+已确认+已派单+已领单+已上门）
		query.setWorkResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
		query.setWorkStatus(Lists.newArrayList(
				OrderStatusConsts.WORK_STATUS_INPUT,
				OrderStatusConsts.WORK_STATUS_CONFIRM,
				OrderStatusConsts.WORK_STATUS_ASSIGN,
				OrderStatusConsts.WORK_STATUS_DISTRIBUTE,
				OrderStatusConsts.WORK_STATUS_TAKE,
				OrderStatusConsts.WORK_STATUS_VISIT
		));
		// 不查询未成单数据
		query.setNonTagId(OrderTagConsts.TAG_ID_UN_AVAILABLE_SERVICE);

//		if (takeSettle) {
//			query.setExistChannelStatementCanTime(GlobalConsts.YES);
//		}

		// 可结算方式查询
		searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
		searchQuery = this.getNativeSearchQueryByChannelSettle(searchQuery, channelSettleNode, channelId);
		logger.info("[{}] log--剩余服务中--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());

		// 执行查询
		Integer remainServiceCount = orderWorkListBService.countOrderWorkByQuery(searchQuery);
		orderCountDRO.setRemainServiceCount(remainServiceCount);

		//总计完成：账号所有完成订单数(服务完成 + 已完成 + 已收单 + 已算账)
		query = new OrderWorkQuery();
		query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW));
		query.setChannelIdList(Lists.newArrayList(channelId));
		query.setWorkStatus(Lists.newArrayList(
				OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE,
				OrderStatusConsts.WORK_STATUS_COMPLETE,
				OrderStatusConsts.WORK_STATUS_CHECKOUT,
				OrderStatusConsts.WORK_STATUS_ACCOUNT));

		// 不查询未成单数据
		query.setNonTagId(OrderTagConsts.TAG_ID_UN_AVAILABLE_SERVICE);

//		if (takeSettle) {
//			query.setExistChannelStatementCanTime(GlobalConsts.YES);
//		}

		// 可结算方式查询
		searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
		searchQuery = this.getNativeSearchQueryByChannelSettle(searchQuery, channelSettleNode, channelId);
		logger.info("[{}] log--总计完成--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());

		// 执行查询
		Integer totalCompleteOrder = orderWorkListBService.countOrderWorkByQuery(query);
		orderCountDRO.setTotalCompleteOrder(totalCompleteOrder);

		//总订单数：订单总数=服务中+已完成+已取消
		query = new OrderWorkQuery();
		query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW));
		query.setChannelIdList(Lists.newArrayList(channelId));
		//  seo渠道B/G/H/E/D针对这几个渠道 ， 在小程序端口或者商家门户，隐藏弃单的订单。同列表过滤
		//  渠道ID:1451，1519，33034，1442，1438
		List<Integer> speChannel = Arrays.asList(1451, 33034, 1442, 1438);
		if (speChannel.contains(channelId)) {
			query.setResultStatusList(Lists.newArrayList(OrderStatusConsts.WORK_RESULT_DOING, OrderStatusConsts.WORK_RESULT_SUCCESS, OrderStatusConsts.WORK_RESULT_FAIL));
		}

		// 不查询未成单数据
		query.setNonTagId(OrderTagConsts.TAG_ID_UN_AVAILABLE_SERVICE);

//		if (takeSettle) {
//			query.setExistChannelStatementCanTime(GlobalConsts.YES);
//		}

		// 可结算方式查询
		searchQuery = orderWorkListBService.getSearchQueryByQuery(query);
		searchQuery = this.getNativeSearchQueryByChannelSettle(searchQuery, channelSettleNode, channelId);
		logger.info("[{}] log--总订单数--->{}, {}", TAG, channelId, searchQuery.getQuery().toString());

		// 执行查询
		Integer totalOrderCount = orderWorkListBService.countOrderWorkByQuery(query);
		orderCountDRO.setTotalOrderCount(totalOrderCount);

		return ResponseUtil.responseSuccess(orderCountDRO, GlobalConsts.SUCCESS_MSG);
	}

	/**
	 * 是否为领单可结算
	 * @param channelId
	 * @return
	 */
	private boolean takeSettle(Integer channelId) {
		// 判断渠道结算方式
		com.zmn.common.dto2.ResponseDTO<ChannelSettleDRO> resp = channelSettleListRemoteService.getByChannelId(channelId);
		logger.info("#oms#判断渠道结算方式getSettleByChannelId入参channelId={},出参resp={}", channelId, resp.getData());
		if (!resp.isSuccess() || Objects.isNull(resp.getData())) {
			return false;
		}
		// 1完成 2领单(领单节点结算 设置 渠道可结算时间)
		if (Objects.equals(GlobalConsts.YES, resp.getData().getSettleNode())) {
			return true;
		}
		return false;
	}

	/**
	 * 获取可结算节点
	 *
	 * @param channelId
	 * @return
	 */
	private ChannelSettleNodeEnum getChannelSettleNode(Integer channelId) {
		// 判断渠道结算方式
		com.zmn.common.dto2.ResponseDTO<ChannelSettleDRO> resp = channelSettleListRemoteService.getByChannelId(channelId);
		logger.info("#oms#判断渠道结算方式getSettleByChannelId入参channelId={},出参resp={}", channelId, resp.getData());
		ChannelSettleDRO settleDRO = resp.getData();

		if (!resp.isSuccess() || Objects.isNull(settleDRO) || settleDRO.getSettleNode() == null) {
			return ChannelSettleNodeEnum.FULFILL;
		}

		// 1完成 2领单(领单节点结算 设置 渠道可结算时间)
		if (Objects.equals(ChannelSettleNodeEnum.GET_A_SINGLE.getCode(), resp.getData().getSettleNode())) {
			return ChannelSettleNodeEnum.GET_A_SINGLE;
		}
		return ChannelSettleNodeEnum.FULFILL;
	}

}
